﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace doveData.XmlScripts
{
    public class LineXml : XmlHelper
    {
        public static string path;
        static List<object> list;

        public LineXml()
        {
            SetXmlPath();
        }

        public void AddXElement()
        {
            int flag;
            while (true)
            {
                Console.WriteLine("\t\t\t\t\t欢迎使用线路增加服务，请输入对应的操作数：");
                Console.WriteLine("\t\t\t\t\t1.增加某线路的站点信息");
                Console.WriteLine("\t\t\t\t\t2.增加新的线路");
                Console.WriteLine("\t\t\t\t\t0.退出本操作");
                Console.Write("\t\t\t\t\t");
                try
                {
                    flag = int.Parse(Console.ReadLine());
                }
                catch (Exception e)
                {
                    Console.WriteLine("\t\t\t\t\t抱歉，请输入有效的操作码");
                    continue;
                }
                if (flag == 0) break;
                switch (flag)
                {
                    case 1:
                        AddComponent();
                        break;
                    case 2:
                        AddAll();
                        break;
                    default:
                        break;
                }
            }
        }

        private void AddComponent()
        {
            int operateNum;
            while (true)
            {
                Console.WriteLine("\t\t\t\t\t您选择的是在已有线路增加站点，输入1继续操作，输入0退出操作");
                Console.Write("\t\t\t\t\t");
                try
                {
                    operateNum = int.Parse(Console.ReadLine());
                }
                catch (Exception e)
                {
                    Console.WriteLine("\t\t\t\t\t抱歉，请输入有效的操作码");
                    continue;
                }
                if (operateNum == 0) break;
                switch (operateNum)
                {
                    case 1:
                        AddCompoentFunction();
                        break;
                    default:
                        Console.WriteLine("\t\t\t\t\t抱歉，您输入的信息有误，请重试！");
                        break;
                }
            }
   }

        private void AddCompoentFunction()
            {
            string newId;
                XElement xml = XElement.Load(path);
                Console.WriteLine("\t\t\t\t\t请按要求输入数据：");
                Console.WriteLine("\t\t\t\t\t您要增加的站点在哪一条线路?请输入该线路的序号:");
            Console.Write("\t\t\t\t\t");
            while (true)
            {
                try
                {
                    newId = Console.ReadLine();
                }
                catch (Exception e)
                {
                    Console.WriteLine("\t\t\t\t\t抱歉，请输入有效的操作码");
                    continue;
                }
                break;
            }
            var query = from x in xml.Descendants("id")
                            where
                            x.Attribute("index").Value == newId
                            select x;

                if (query.Count() == 0) { Console.WriteLine("\t\t\t\t\t抱歉，这条线路并不存在，请重新输入！"); }
                else
                {
                    Console.WriteLine("\t\t\t\t\t该线路的站点信息如下：");
                    foreach (var item in (query.Elements()))
                    {
                        Console.WriteLine("\t\t\t\t\t\t"+item.Value);
                    }

                Console.WriteLine("\t\t\t\t\t新建的站在哪个站的旁边？请输入这个已有的站：");
                Console.Write("\t\t\t\t\t");
                string oldStation = Console.ReadLine();

                var query1 = from y in query.Descendants("st")
                             where
                             y.Value == oldStation
                             select y;

                if (query1.Count() > 0)
                {
                    Console.WriteLine("\t\t\t\t\t新站在已有站的前一站还是后一站？输入0表示前，1表示后：");
                    Console.Write("\t\t\t\t\t");
                    int opNum = int.Parse(Console.ReadLine());

                    Console.WriteLine("\t\t\t\t\t新站的名称是什么？请输入名称：");
                    Console.Write("\t\t\t\t\t");
                    string newName = Console.ReadLine();

                    Console.WriteLine("\t\t\t\t\t新站的x坐标是多少？请输入：");
                    Console.Write("\t\t\t\t\t");
                    string newX = Console.ReadLine();

                    Console.WriteLine("\t\t\t\t\t新站的y坐标是多少？请输入：");
                    Console.Write("\t\t\t\t\t");
                    string newY = Console.ReadLine();

                    
                    var stList = query.ElementAt(0).Elements("st");
                    switch (opNum)
                    {
                        case 0:
                            XElement newStation = new XElement
                                ("st", newName, 
                                new XAttribute("index", query1.ElementAt(0).Attribute("index").Value),
                                new XAttribute("x",newX),
                                new XAttribute("y",newY));

                            var res = from z in stList
                                      where
                                      int.Parse(z.Attribute("index").Value) 
                                      >= 
                                      int.Parse(query1.ElementAt(0).Attribute("index").Value)
                                      select z;

                            foreach (var item in res)
                            {
                                string newAttri = (int.Parse(item.Attribute("index").Value) + 1).ToString();
                                item.SetAttributeValue("index",newAttri);
                            }
                            query1.ElementAt(0).AddBeforeSelf(newStation);
                            xml.Save(path);
                            Console.WriteLine("\t\t\t\t\t增加成功！");
                            break;

                        case 1:
                            XElement newStation1 = new XElement
                                ("st", newName, 
                                new XAttribute("index", (int.Parse(query1.ElementAt(0).Attribute("index").Value)+1).ToString()),
                                new XAttribute("x",newX),
                                new XAttribute("y",newY));
                            var res1 = from z in stList
                                      where
                                      int.Parse(z.Attribute("index").Value) 
                                      >
                                      int.Parse(query1.ElementAt(0).Attribute("index").Value)
                                      select z;

                            //Console.WriteLine(res1.Count());
                            foreach (var item in res1)
                            {
                                string newAttri = (int.Parse(item.Attribute("index").Value) + 1).ToString();
                                item.SetAttributeValue("index", newAttri);
                                
                            }
                            query1.ElementAt(0).AddAfterSelf(newStation1);
                            xml.Save(path);
                            Console.WriteLine("\t\t\t\t\t增加成功！");
                            break;
                        default:
                            Console.WriteLine("\t\t\t\t\t抱歉，您输入有误，请重试！");
                            return;
                    }
                }
                else
                {
                    Console.WriteLine("\t\t\t\t\t抱歉，该线路没有这个已知站，请重新输入！");
                    return;
                }
            }
            }

        private void AddAll()
        {
            while (true)
            {
                Console.WriteLine("\t\t\t\t\t您选择的是增加新的线路，输入1继续操作，输入0退出操作");
                Console.Write("\t\t\t\t\t");
                int operateNum = int.Parse(Console.ReadLine());
                if (operateNum == 0) break;
                switch (operateNum)
                {
                    case 1:
                        AddAllFunction();
                        break;
                    default:
                        Console.WriteLine("\t\t\t\t\t抱歉，您的输入有误，请重试");
                        break; 
                }
            }
        }

        private void AddAllFunction()
        {
            XElement xml = XElement.Load(path);
            Console.WriteLine("\t\t\t\t\t请按要求输入数据：");
            Console.Write("\t\t\t\t\t新增线路的序号：");
            Console.Write("\t\t\t\t\t");
            string newId = Console.ReadLine();

            var query = from x in xml.Descendants("id")
                        where
                        x.Attribute("index").Value == newId
                        select x;

            if (query.Count() > 0)
            {
                Console.WriteLine("\t\t\t\t\t抱歉，您要添加的线路已经存在!请重新输入");
                return;
            }
            string newName = newId + "号线";

            Console.WriteLine("\t\t\t\t\t该线路有多少个站？");
            Console.Write("\t\t\t\t\t");
            int num = int.Parse(Console.ReadLine());
            string[] stations = new string[num];
            string[] Xs = new string[num];
            string[] Ys = new string[num];
            for (int i = 0; i <= num - 1; i++)
            {
                Console.WriteLine("\t\t\t\t\t请输入第" + (i+1) + "个站的名称：");
                Console.Write("\t\t\t\t\t");
                stations[i] = Console.ReadLine();
                Console.WriteLine("\t\t\t\t\t请输入第" + (i + 1) + "个站的x坐标：");
                Console.Write("\t\t\t\t\t");
                Xs[i] = Console.ReadLine();
                Console.WriteLine("\t\t\t\t\t请输入第" + (i + 1) + "个站的y坐标：");
                Console.Write("\t\t\t\t\t");
                Ys[i] = Console.ReadLine();

            }
            XElement xId = new XElement("id", new XAttribute("index", newId));
            XElement xName = new XElement("name", newName);
            xId.Add(xName);
            for (int i = 0; i <= num - 1; i++)
            {
                XElement newElement = new XElement("st", stations[i], 
                    new XAttribute("index", i),
                    new XAttribute("x",Xs[i]),
                    new XAttribute("y",Ys[i]));
                xId.Add(newElement);
            }
            xml.Add(xId);
            xml.Save(path);
            Console.WriteLine("\t\t\t\t\t增加成功！");
        }

        public void DeleteElement()
            {
            int flag;
                while (true)
                {
                Console.WriteLine("\t\t\t\t\t1.删除某线路的站点信息");
                Console.WriteLine("\t\t\t\t\t2.删除某线路的全部信息");
                Console.WriteLine("\t\t\t\t\t0.退出本操作");
                Console.Write("\t\t\t\t\t");
                try
                {
                    flag = int.Parse(Console.ReadLine());
                }
                catch (Exception e)
                {
                    Console.WriteLine("\t\t\t\t\t抱歉，请输入有效的操作码");
                    continue;
                }
                switch (flag)
                    {
                        case 1:
                            DeleteCompoent();
                            break;
                        case 2:
                            DeleteAll();
                            break;
                        default:
                            Console.WriteLine("\t\t\t\t\t输入有误，请重试！");
                            break;
                    }
                    if (flag == 0) break;
                } 
            
        }

        private void DeleteCompoent()
        {
            XElement xml = XElement.Load(path);

                    Console.WriteLine("\t\t\t\t\t请问您想操作的是几号线？");
                    Console.Write("\t\t\t\t\t");
                    string id = Console.ReadLine();

                    Console.WriteLine("\t\t\t\t\t请问您想删除" + id + "号线的第几个站？");
                    Console.Write("\t\t\t\t\t");
                    string findNum = Console.ReadLine();

            if (int.Parse(findNum) <= 0)
            {
                Console.WriteLine("\t\t\t\t\t您的输入有误，请重试！");
                return;
            }

            var query = from p in xml.Descendants("id")
                        where 
                        p.Attribute("index").Value == id
                        select p;
            var query1 = from y in query.Descendants("st")
                                      where
                                      y.Attribute("index").Value == (int.Parse(findNum)-1).ToString()
                                      select y;
            if (query.Count() > 0&&query1.Count()>0)
            {
                var stList = query.ElementAt(0).Elements("st");
                var afterList = from z in stList
                                where
                                int.Parse(z.Attribute("index").Value)
                                >
                                int.Parse(query1.ElementAt(0).Attribute("index").Value)
                                select z;
                foreach (var item in afterList)
                {
                    string newAttri = (int.Parse(item.Attribute("index").Value) - 1).ToString();
                    item.SetAttributeValue("index", newAttri);
                }
                query1.ElementAt(0).Remove();
                xml.Save(path);
                Console.WriteLine("\t\t\t\t\t成功删除！");
            }
            else { Console.WriteLine("\t\t\t\t\t抱歉，不存在这条线路或站点！"); }
        }

        private void DeleteAll()
        {
            XDocument xml = XDocument.Load(path);

            Console.WriteLine("\t\t\t\t\t请输入您要删除的线路序号：");
            Console.Write("\t\t\t\t\t");
            string id = Console.ReadLine();

            var query = from p in xml.Descendants("id") where p.Attribute("index").Value == id select p;
            if (query.Count() > 0)
            {
                query.Remove();
                xml.Save(path);
                Console.WriteLine("\t\t\t\t\t删除" + id + "号线成功！");
            }
            else
            {
                Console.WriteLine("\t\t\t\t\t抱歉，您的输入有误，请输入已存在的线路序号！");
                return;
            }

        }

        public XElement LoadXML()
        {
            if (path == null)
                return null;
            XElement xml = XElement.Load(path);
            return xml;
        }

        public void ModifyElement()
        {
            Console.WriteLine("\t\t\t\t\t请先参考站点信息:");
            Output();
            XDocument xml = XDocument.Load(path);

            Console.WriteLine("\t\t\t\t\t请输入您要修改的线路序号：");
            Console.Write("\t\t\t\t\t");
            string id = Console.ReadLine();
            string findName = id + "号线";

            var stList = from x in xml.Descendants("st")
                         where x.Parent.Attribute("index").Value == id
                         select x;

                Console.WriteLine("\t\t\t\t\t请问您要修改第几个站的信息？");
                Console.Write("\t\t\t\t\t");
                int findNum = int.Parse(Console.ReadLine()) - 1;
                if (findNum + 1 > stList.Count())
                {
                    Console.WriteLine("抱歉，该线路没有这么多站，请重新输入!");
                    return;
                }

                Console.WriteLine("\t\t\t\t\t请问您要把该站点名称修改为：");
                Console.Write("\t\t\t\t\t");
                string newStation = Console.ReadLine();

                Console.WriteLine("\t\t\t\t\t请问您要把该站点的x坐标修改为：");
                Console.Write("\t\t\t\t\t");
                string newX = Console.ReadLine();

                Console.WriteLine("\t\t\t\t\t请问您要把该站点的y坐标修改为：");
                Console.Write("\t\t\t\t\t");
                string newY = Console.ReadLine();



            var query = from x in xml.Descendants("st")
                        where x.Parent.Attribute("index").Value.Equals(id)//线路
                        &&x.Attributes().ElementAt(0).Value== findNum.ToString()
                        select x;

            if (query.Count() > 0)
            {
                query.ElementAt(0).SetValue(newStation);
                query.ElementAt(0).Attribute("x").SetValue(newX);
                query.ElementAt(0).Attribute("y").SetValue(newY);
                Console.WriteLine("\t\t\t\t\t修改成功！");
            }
            else { Console.WriteLine("\t\t\t\t\t抱歉，不存在这条线路！"); }

            xml.Save(path);
        }
        public void Output()
        {
             XElement myxml = LoadXML();
            //XDocument myxml = XDocument.Load(path);

            var query = from q in myxml.Elements().Elements()
                        select q;

            

            foreach (var item in query)
            {
                if (item.Attribute("index") != null)//输出有index属性的元素的属性以及元素值
                    Console.WriteLine("\t\t\t\t\t第" + (int.Parse(item.Attribute("index").Value) + 1).ToString() + "个站：" + item.Value);
                else//输出XX号线（没有index属性）
                {
                    Console.WriteLine("\t\t\t\t\t" + item.Value);
                }
                if (item.Attribute("x") != null && item.Attribute("y") != null)
                {
                    Console.WriteLine("\t\t\t\t\tx坐标为：" + item.Attribute("x").Value + " "+"y坐标为：" + item.Attribute("y").Value);
                }
                Console.WriteLine("");

            }

        }

        public void SetXmlPath()
        {
            path = "..//..//xml//lineInfo.txt";
        }
    }
}
